package com.tanhua.server.service;

import com.google.errorprone.annotations.Var;
import com.tanhua.autoconfig.templates.OssTemplate;
import com.tanhua.domain.db.User;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Movement;
import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.mongo.Visitors;
import com.tanhua.domain.vo.MovementsVo;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.RecommendUserVo;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.dubbo.api.mongo.MovementApi;
import com.tanhua.dubbo.api.mongo.RecommendUserApi;
import com.tanhua.dubbo.api.mongo.VisitorApi;
import com.tanhua.server.utils.RelativeDateFormat;
import com.tanhua.server.utils.UserHolder;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class MovementsService {

    @Autowired
    private OssTemplate ossTemplate;

    @Reference
    private MovementApi movementApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private CommentApi commentApi;

    @Reference
    private RecommendUserApi recommendUserApi;


    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate  rocketMQTemplate;


    public ResponseEntity saveMovements(Movement movement , MultipartFile[] imageContent) throws Exception {
//        把图片上传到阿里云
        List<String> medias = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(upload);
        }
        movement.setMedias(medias);
        movement.setUserId(UserHolder.getUserId()); //
        //        直接调用dubbo服务
        String movementId = movementApi.saveMovements(movement);
//        把这个需要审核的动态的id放入到MQ中
        rocketMQTemplate.convertAndSend("movement_huawei_check",movementId);

        return ResponseEntity.ok(null);

    }

    public ResponseEntity queryFriendMovements(Integer page, Integer pagesize) {
//        假如  当前登录人是2号用户 查询的表是 movement_friend_2
//        关联movement_detail表中的数据
        Long userId = UserHolder.getUserId();
       PageResult pageResult = movementApi.queryFriendMovements(userId,page,pagesize);
        List<Movement> movementList = (List<Movement>) pageResult.getItems();
//        但是这个集合也不是app所需要的
//        把movementList中的一个一个的Movement转成一个一个的MovementsVo
//        MovementsVo既有用户的信息UserInfo也有Movement的信息

        List<MovementsVo> movementVoList = new ArrayList<>();
        for (Movement movement : movementList) {
            UserInfo userInfo = userInfoApi.findById(movement.getUserId());
            MovementsVo movementsVo = movementAndUserInfoToMovementVo(movement, userInfo);
            movementVoList.add(movementsVo);
        }
        pageResult.setItems(movementVoList);
        return ResponseEntity.ok(pageResult);
    }

    public MovementsVo movementAndUserInfoToMovementVo(Movement movement, UserInfo userInfo) {
        //            把UserInfo的内容放到MovementVo
        MovementsVo movementsVo = new MovementsVo();
        BeanUtils.copyProperties(userInfo,movementsVo);
        movementsVo.setUserId(userInfo.getId());
        if(userInfo.getTags()!=null){
            movementsVo.setTags(userInfo.getTags().split(","));
        }
//            把Movement的内容放到MovementVo
        BeanUtils.copyProperties(movement,movementsVo);
        movementsVo.setId(movement.getId().toString());//动态id //注意这个的id需要手动赋值
        movementsVo.setImageContent(movement.getMedias().toArray(new String[]{})); //集合转成字符串数据
        movementsVo.setDistance("500米以内"); //先随便给一个值
        movementsVo.setCreateDate(RelativeDateFormat.format(new Date(movement.getCreated())));

        if(redisTemplate.hasKey("publish_like_"+movement.getId().toString()+"_"+UserHolder.getUserId())){
            movementsVo.setHasLiked(1);  // 代表当前登录人已对这个圈子点赞
        }else{
            movementsVo.setHasLiked(0);  // 代表当前登录人已对这个圈子未点赞
        }

        if(redisTemplate.hasKey("publish_love_"+movement.getId().toString()+"_"+UserHolder.getUserId())){
            movementsVo.setHasLoved(1);  // 代表当前登录人已对这个圈子喜欢
        }else{
            movementsVo.setHasLoved(0);  // 代表当前登录人已对这个圈子未喜欢
        }


        return movementsVo;
    }

    public ResponseEntity queryRecommendMovements(Integer page, Integer pagesize) {

//        关联movement_detail表中的数据
        Long userId = UserHolder.getUserId();
//        先从redis中查询，如果redis中没有再查mongo
        PageResult pageResult = movementApi.queryRecommendMovements(userId,page,pagesize);
        List<Movement> movementList = (List<Movement>) pageResult.getItems();
//        但是这个集合也不是app所需要的
//        把movementList中的一个一个的Movement转成一个一个的MovementsVo
//        MovementsVo既有用户的信息UserInfo也有Movement的信息
        List<MovementsVo> movementVoList = new ArrayList<>();
        for (Movement movement : movementList) {
            UserInfo userInfo = userInfoApi.findById(movement.getUserId());
            MovementsVo movementsVo = movementAndUserInfoToMovementVo(movement, userInfo);
            movementVoList.add(movementsVo);
        }
        pageResult.setItems(movementVoList);
        return ResponseEntity.ok(pageResult);



    }

//    查询自己的动态，只看审核通过的
    public ResponseEntity queryMySelfMovements(Integer page, Integer pagesize,Long userId) {
//        优先查询userId对应的动态 如果没有userId查询当前登录人的动态
        if(userId==null){
            userId = UserHolder.getUserId();
        }
        //        关联movement_detail表中的数据'
        PageResult pageResult = movementApi.queryMySelfMovements(userId,page,pagesize);
        List<Movement> movementList = (List<Movement>) pageResult.getItems();
//        但是这个集合也不是app所需要的
//        把movementList中的一个一个的Movement转成一个一个的MovementsVo
//        MovementsVo既有用户的信息UserInfo也有Movement的信息
        List<MovementsVo> movementVoList = new ArrayList<>();
        UserInfo userInfo = userInfoApi.findById(userId);
        for (Movement movement : movementList) {

            if(movement.getState()!=1){
                continue;
            }

            MovementsVo movementsVo = movementAndUserInfoToMovementVo(movement, userInfo);
            movementVoList.add(movementsVo);
        }
        pageResult.setItems(movementVoList);
        return ResponseEntity.ok(pageResult);


    }

//    圈子点赞
    public ResponseEntity movementLike(String movementId) {
//        1、保存comment数据
//        2、在圈子的点赞数+1
//        3、返回这个圈子的点赞数
        Comment comment = new Comment();
        comment.setUserId(UserHolder.getUserId());
        comment.setPublishId(new ObjectId(movementId)); //把字符串转成ObjectId
        comment.setCommentType(1); //评论类型，1-动态点赞，2-动态评论，3-动态喜欢 4-视频点赞  5-视频评论  6-评论点赞
        comment.setContent(""); //这是个点赞的操作 没有描述
        Integer count = commentApi.saveComment(comment); // 返回这个圈子的点赞数

//        把当前登录人对这个圈子的点赞存储到redis中    如果redis中有这个key 就表示当前登录人对这个圈子已经点赞了
        redisTemplate.boundValueOps("publish_like_"+movementId+"_"+UserHolder.getUserId()).set("");

        return ResponseEntity.ok(count);
    }

//    圈子取消点赞
    public ResponseEntity movementDislike(String movementId) {
//        1、删除comment数据   比作mysql SQL语句： delete from  comment  where publishId=?? and userId=? and commentType=1
//        2、在圈子的点赞数-1
//        3、返回这个圈子的点赞数
        Comment comment = new Comment();
        comment.setUserId(UserHolder.getUserId());
        comment.setPublishId(new ObjectId(movementId)); //把字符串转成ObjectId
        comment.setCommentType(1); //评论类型，1-动态点赞，2-动态评论，3-动态喜欢 4-视频点赞  5-视频评论  6-评论点赞
        Integer count = commentApi.deleteComment(comment); // 返回这个圈子的点赞数
//        删除当前登录人对这个圈子的点赞标记
        redisTemplate.delete("publish_like_"+movementId+"_"+UserHolder.getUserId());
        return ResponseEntity.ok(count);
    }

    public ResponseEntity movementlove(String movementId) {

        //        1、保存comment数据
//        2、在圈子的喜欢数+1
//        3、返回这个圈子的喜欢数
        Comment comment = new Comment();
        comment.setUserId(UserHolder.getUserId());
        comment.setPublishId(new ObjectId(movementId)); //把字符串转成ObjectId
        comment.setCommentType(3); //评论类型，1-动态点赞，2-动态评论，3-动态喜欢 4-视频点赞  5-视频评论  6-评论点赞
        comment.setContent(""); //这是个喜欢的操作 没有描述
        Integer count = commentApi.saveComment(comment); // 返回这个圈子的喜欢数

//        把当前登录人对这个圈子的喜欢存储到redis中    如果redis中有这个key 就表示当前登录人对这个圈子已经喜欢了
        redisTemplate.boundValueOps("publish_love_"+movementId+"_"+UserHolder.getUserId()).set("");

        return ResponseEntity.ok(count);
    }

    public ResponseEntity movementUnlove(String movementId) {
//        1、删除comment数据   比作mysql SQL语句： delete from  comment  where publishId=?? and userId=? and commentType=3
//        2、在圈子的喜欢数-1
//        3、返回这个圈子的喜欢数
        Comment comment = new Comment();
        comment.setUserId(UserHolder.getUserId());
        comment.setPublishId(new ObjectId(movementId)); //把字符串转成ObjectId
        comment.setCommentType(3); //评论类型，1-动态点赞，2-动态评论，3-动态喜欢 4-视频点赞  5-视频评论  6-评论点赞
        Integer count = commentApi.deleteComment(comment); // 返回这个圈子的点赞数
//        删除当前登录人对这个圈子的喜欢标记
        redisTemplate.delete("publish_love_"+movementId+"_"+UserHolder.getUserId());
        return ResponseEntity.ok(count);
    }

    public ResponseEntity queryMovementById(String movementId) {
       Movement movement = movementApi.queryMovementById(movementId);
//       userInfo+movement=MovementsVo
        Long userId = movement.getUserId();
        UserInfo userInfo = userInfoApi.findById(userId);
        MovementsVo movementsVo = movementAndUserInfoToMovementVo(movement, userInfo);
        return ResponseEntity.ok(movementsVo);

    }

    @Reference
    private VisitorApi visitorApi;

    public ResponseEntity queryVisitors() {

//        获取当前登录人上一次访问的时间
        String timeStr = redisTemplate.boundValueOps("VISITOR_TIME_" + UserHolder.getUserId()).get();

        List<Visitors>   visitorsList = null;
        if(timeStr==null){
//        查询visitor表 最多显示4条数据
            visitorsList = visitorApi.queryVisitors(UserHolder.getUserId(),4);
        }else{
//            查询的是这个时间节点之后产生的数据 最多还是显示4条数据
          visitorsList = visitorApi.queryVisitors(UserHolder.getUserId(),Long.parseLong(timeStr),4);
        }

      List<RecommendUserVo> list = new ArrayList<>();
//      把一个一个的Visitors转成RecommendUserVo
        for (Visitors visitors : visitorsList) {
            UserInfo userInfo = userInfoApi.findById(visitors.getVisitorUserId());
            RecommendUserVo recommendUserVo = new RecommendUserVo();
            BeanUtils.copyProperties(userInfo,recommendUserVo);
            if(userInfo.getTags()!=null){
                recommendUserVo.setTags(userInfo.getTags().split(","));
            }
            Long score = recommendUserApi.queryScore(UserHolder.getUserId(), visitors.getVisitorUserId());
            recommendUserVo.setFateValue(score);
            list.add(recommendUserVo);
        }

//        向redis中记录当前访问的时间点  这个时间点在下一次查询时会用到
        redisTemplate.boundValueOps("VISITOR_TIME_"+UserHolder.getUserId()).set(new Date().getTime()+"");

        return ResponseEntity.ok(list);


    }
}
